////////////////////////////////////////////////////////////////////////////////
//
//	Original file Name: Screen.java
//	Originating Author: JWhitefield
//	
//	Description:
//
////////////////////////////////////////////////////////////////////////////////

package com.jjw.game.screen;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Transparency;
import java.awt.image.BufferedImage;

import com.jjw.game.Game;
import com.jjw.game.graphics.Sprite;
import com.jjw.game.world.tile.Tile;

public class Screen {
	
	//--------------------------------------------------------------------------
	//
	//Properties
	//
	//--------------------------------------------------------------------------
	
	//----------------------------------
	// Public
	//----------------------------------

	//----------------------------------
	//  Getters / Setters
	//----------------------------------

	/**
	 * Width of the screen
	 */
	public int getWidth() {
		return this.width;
	}
	
	/**
	 * Height of the screen
	 */
	public int getHeight() {
		return this.height;
	}
	
	//----------------------------------
	// Private
	//----------------------------------

	/**
	 * The x location the screen is to be dawn at
	 */
	private int screenX;
	
	/**
	 * The y location the screen is to be drawn at
	 */
	private int screenY;
	
	/**
	 * Draw Graphics 
	 */
	private Graphics graphics;
	
	/**
	 * Width of the screen 
	 */
	private int width = 0;
	
	/**
	 * Height of the screen
	 */
	private int height = 0;
	
	private int offsetX = 0;
	
	private int offsetY = 0;
	
	/**
	 * Default graphics environment
	 */
	private static GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
	
	/**
	 * Default Screen Device
	 */
	private static GraphicsDevice graphicsDevice = graphicsEnvironment.getDefaultScreenDevice();
	
	/**
	 * Default graphics configuration
	 */
	private static GraphicsConfiguration graphicsConfiguration = graphicsDevice.getDefaultConfiguration();
	
	//--------------------------------------------------------------------------
	//
	//  Methods
	//
	//--------------------------------------------------------------------------
	
	//----------------------------------
	// Public
	//----------------------------------
	
	public Screen(int x, int y, int width, int height) {

		//Set the x and y 
		this.screenX = x;
		this.screenY = y;
		
		//Set the width and height of the screen 
		this.width = width;
		this.height = height;
	}
	

	/**
	 * Render the sprite to the screen 
	 * 
	 * @param x			x position of the sprite
	 * @param y			y position of the sprite 
	 * @param sprite	sprite to be rendered
	 */
	public void render(int x, int y, Sprite sprite) {

		//If we don't have a sprite we can't render it
		if( sprite == null )
			return;
		
		//Alter the x and y values to use the offsets 
		x = x - this.offsetX;
		y = y - this.offsetY;
		
		//Get the right edge x position of the sprite 
		int rightEdgeX = x + sprite.getWidth(); 
		
		//Get the bottom edge of the y position of the sprite 
		int bottomEdgeY = y + sprite.getHeight();
				
		//Check its not off either side
		if( rightEdgeX <= 0 || x > this.width  )
			return;
		
		//Check its not off top or bottom
		if( bottomEdgeY <= 0 || y > this.height )
			return;
		
		//If neither of these draw the sprite to the screen, if we have graphics
		if( this.graphics != null )
		{			
			//Adjusted x and y for the sprite
			int spriteX = x + this.screenX;
			int spriteY = y + this.screenY;
			
			//Adjusted width and height of the sprite
			int spriteWidth = sprite.getWidth();
			int spriteHeight = sprite.getHeight();
			
			//Sprite image
			BufferedImage spriteImage = sprite.getImage();
			
			if( rightEdgeX < Tile.DEFAULT_TILE_SIZE )
			{
				spriteImage = spriteImage.getSubimage( spriteImage.getWidth() - rightEdgeX , 0, rightEdgeX, spriteImage.getHeight());
				spriteX = this.screenX;
				spriteWidth = rightEdgeX;
			}

			//
			if( bottomEdgeY < Tile.DEFAULT_TILE_SIZE )
			{
				spriteImage = spriteImage.getSubimage( 0, spriteImage.getHeight() - bottomEdgeY, spriteImage.getWidth(), bottomEdgeY);
				spriteY = this.screenY;
				spriteHeight = bottomEdgeY;
			}
			
			//Draw sprite
			this.graphics.drawImage(spriteImage, spriteX, spriteY, null );
			
			//If the game is in debug draw debug constraints
			if( Game.DEBUG )
			{
				//Set red outline for debug colour
				this.graphics.setColor(Color.RED);
				
				//Draw the sprite bounds
				this.graphics.drawRect(spriteX, spriteY, spriteWidth , spriteHeight);
				
				//Draw the screens bounds
				this.drawScreenBounds();
			}
		}
	}
	
	/**
	 * Set the drawing graphics 
	 */
	public void setGraphics( Graphics g ) {
		
		//Set the graphics to render to 
		this.graphics = g;
	}
	
	/**
	 * Sets the screens offsets 
	 * 
	 * @param xOffset
	 * @param yOffset
	 */
	public void setOffset( int xOffset, int yOffset ) {

		//Set the properties
		this.offsetX = xOffset;
		this.offsetY = yOffset;
	}
	
	/**
	 * Creates a compatible image with this graphics environment 
	 * 
	 * @param image
	 */
	public static BufferedImage createCompatibleImage( BufferedImage image ) {
				 
		//Create a compatible image
		BufferedImage compatibleImage = graphicsConfiguration.createCompatibleImage(image.getWidth(), image.getHeight(), Transparency.TRANSLUCENT);
		
		//Get the 2d graphics for the compatible image 
		Graphics2D g = compatibleImage.createGraphics();
		
		//Draw image onto the graphics of another image 
		g.drawImage(image , 0, 0, null);
		
		//Dispose the graphics 
		g.dispose();
		
		//Return the compatible image
		return compatibleImage;
	}
	
	//----------------------------------
	// Private
	//----------------------------------
	
	/**
	 * Draws the bounds of the screen 
	 */
	private void drawScreenBounds() {
		
		//Check that we are in debug
		if( Game.DEBUG ) {
			
			//Set the colour to blue
			this.graphics.setColor(Color.BLUE);
			
			//Draw a rectangle which shows the screen bounds 
			this.graphics.drawRect( this.screenX , this.screenY, this.width, this.height);
		}
	}
	
	//----------------------------------
	// Overridden / Implemented
	//----------------------------------
}
